package net.funtip.jdbc.driver;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;

import net.funtip.jdbc.JDBCLogger;

public class FTStatement implements Statement {

	protected Statement realStatement;

	protected FTConnection connectionParent;

	protected String lastSql;

	public FTStatement(Statement statement, FTConnection parent) {
		realStatement = statement;
		connectionParent = parent;
	}

	protected JDBCLogger getJdbcLogger() throws SQLException {
		return JDBCLogger.getInstance();
	}

	public void addBatch(String sql) throws SQLException {
		realStatement.addBatch(sql);
		lastSql = sql;
	}

	public void cancel() throws SQLException {
		realStatement.cancel();
	}

	public void clearBatch() throws SQLException {
		realStatement.clearBatch();
	}

	public void clearWarnings() throws SQLException {
		realStatement.clearWarnings();
	}

	public void close() throws SQLException {
		getJdbcLogger().closeStatement();
		realStatement.close();
	}

	public boolean execute(String sql) throws SQLException {
		try {
			getJdbcLogger().startLogSqlQuery(sql);
			boolean b = realStatement.execute(sql);
			lastSql = sql;
			return b;
		} finally {
			getJdbcLogger().endLogSqlQuery(sql);
		}

	}

	public int[] executeBatch() throws SQLException {
		try {
			getJdbcLogger().startLogSqlQuery(lastSql);
			int[] i = realStatement.executeBatch();
			return i;
		} finally {
			getJdbcLogger().endLogSqlQuery(lastSql);
		}
	}

	public ResultSet executeQuery(String sql) throws SQLException {
		try {
			getJdbcLogger().startLogSqlQuery(sql);
			ResultSet r = realStatement.executeQuery(sql);
			lastSql = sql;
			return new FTResultSet(r, this, sql);
		} finally {
			getJdbcLogger().endLogSqlQuery(sql);
		}
	}

	public int executeUpdate(String sql) throws SQLException {
		try {
			getJdbcLogger().startLogSqlQuery(sql);
		int i = realStatement.executeUpdate(sql);
		lastSql = sql;
		return i;
		} finally {
			getJdbcLogger().endLogSqlQuery(sql);
		}
	}

	public Connection getConnection() throws SQLException {
		return connectionParent;
	}

	public int getFetchDirection() throws SQLException {
		return realStatement.getFetchDirection();
	}

	public int getFetchSize() throws SQLException {
		return realStatement.getFetchSize();
	}

	public int getMaxFieldSize() throws SQLException {
		return realStatement.getMaxFieldSize();
	}

	public int getMaxRows() throws SQLException {
		return realStatement.getMaxRows();
	}

	public boolean getMoreResults() throws SQLException {
		return realStatement.getMoreResults();
	}

	public int getQueryTimeout() throws SQLException {
		return realStatement.getQueryTimeout();
	}

	public ResultSet getResultSet() throws SQLException {
		return new FTResultSet(realStatement.getResultSet(), this, lastSql);
	}

	public int getResultSetConcurrency() throws SQLException {
		return realStatement.getResultSetConcurrency();
	}

	public int getResultSetType() throws SQLException {
		return realStatement.getResultSetType();
	}

	public int getUpdateCount() throws SQLException {
		return realStatement.getUpdateCount();
	}

	public SQLWarning getWarnings() throws SQLException {
		return realStatement.getWarnings();
	}

	public void setCursorName(String name) throws SQLException {
		realStatement.setCursorName(name);
	}

	public void setEscapeProcessing(boolean enable) throws SQLException {
		realStatement.setEscapeProcessing(enable);
	}

	public void setFetchDirection(int direction) throws SQLException {
		realStatement.setFetchDirection(direction);
	}

	public void setFetchSize(int rows) throws SQLException {
		realStatement.setFetchSize(rows);
	}

	public void setMaxFieldSize(int max) throws SQLException {
		realStatement.setMaxFieldSize(max);
	}

	public void setMaxRows(int max) throws SQLException {
		realStatement.setMaxRows(max);
	}

	public void setQueryTimeout(int seconds) throws SQLException {
		realStatement.setQueryTimeout(seconds);
	}

	/**
	 * @see java.sql.Statement#execute(String, int)
	 */
	public boolean execute(String sql, int i) throws SQLException {
		try {
			getJdbcLogger().startLogSqlQuery(sql);
			return realStatement.execute(sql,i);
		} finally {
			getJdbcLogger().endLogSqlQuery(sql);
		}
	}

	/**
	 * @see java.sql.Statement#execute(String, int[])
	 */
	public boolean execute(String sql, int[] i) throws SQLException {
		try {
			getJdbcLogger().startLogSqlQuery(sql);
			return realStatement.execute(sql,i);
		} finally {
			getJdbcLogger().endLogSqlQuery(sql);
		}
	}

	/**
	 * @see java.sql.Statement#execute(String, String[])
	 */
	public boolean execute(String sql, String[] s) throws SQLException {
		try {
			getJdbcLogger().startLogSqlQuery(sql);
			return realStatement.execute(sql,s);
		} finally {
			getJdbcLogger().endLogSqlQuery(sql);
		}
	}

	/**
	 * @see java.sql.Statement#executeUpdate(String, int)
	 */
	public int executeUpdate(String sql, int i) throws SQLException {
		try {
			getJdbcLogger().startLogSqlQuery(sql);
			return realStatement.executeUpdate(sql,i);
		} finally {
			getJdbcLogger().endLogSqlQuery(sql);
		}
	}

	/**
	 * @see java.sql.Statement#executeUpdate(String, int[])
	 */
	public int executeUpdate(String sql, int[] i) throws SQLException {
		try {
			getJdbcLogger().startLogSqlQuery(sql);
			return realStatement.executeUpdate(sql,i);
		} finally {
			getJdbcLogger().endLogSqlQuery(sql);
		}
	}

	/**
	 * @see java.sql.Statement#executeUpdate(String, String[])
	 */
	public int executeUpdate(String sql, String[] s) throws SQLException {
		try {
			getJdbcLogger().startLogSqlQuery(sql);
			return realStatement.executeUpdate(sql,s);
		} finally {
			getJdbcLogger().endLogSqlQuery(sql);
		}
	}

	/**
	 * @see java.sql.Statement#getGeneratedKeys()
	 */
	public ResultSet getGeneratedKeys() throws SQLException {
		return realStatement.getGeneratedKeys();
	}

	/**
	 * @see java.sql.Statement#getMoreResults(int)
	 */
	public boolean getMoreResults(int arg0) throws SQLException {
		return realStatement.getMoreResults(arg0);
	}

	/**
	 * @see java.sql.Statement#getResultSetHoldability()
	 */
	public int getResultSetHoldability() throws SQLException {
		return realStatement.getResultSetHoldability();
	}

	public boolean isClosed() throws SQLException {
		return realStatement.isClosed();
	}

	public boolean isPoolable() throws SQLException {
		return realStatement.isPoolable();
	}

	public void setPoolable(boolean poolable) throws SQLException {
		realStatement.setPoolable(poolable);
	}

	public boolean isWrapperFor(Class<?> iface) throws SQLException {
		return realStatement.isWrapperFor(iface);
	}

	public <T> T unwrap(Class<T> iface) throws SQLException {
		return realStatement.unwrap(iface);
	}

	public void closeOnCompletion() throws SQLException {
		// TODO implement when using JDK 1.7
	}

	public boolean isCloseOnCompletion() throws SQLException {
		// TODO implement when using JDK 1.7
		return false;
	}

}

